package tjs.styudy.mini.springboot.transaction.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import tjs.styudy.mini.springboot.transaction.config.TransactionInfo;
import tjs.styudy.mini.springboot.transaction.config.TransactionManager;

/**
 * Created by Nicky.Tang on 2021/10/27 5:20 下午
 *
 * @since 02.12.10
 */
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)//开启aop
public class TransactionAspect {

    private TransactionManager transactionManager;

    public TransactionAspect(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    @Pointcut(value = "@within(tjs.styudy.mini.springboot.transaction.aop.MiniTransactional)")
    public void point() {
    }

    @Around("point()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object res = null;
        MiniTransactional miniTransactional = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(MiniTransactional.class);

        //1. 实例化TransactionInfo
        TransactionInfo transactionInfo =  transactionManager.createTransactionIfNecessary(miniTransactional);
        try {
            //2. 调用目标方法
            res = joinPoint.proceed();
        } catch (Exception ex) {
            //3.1 回滚事务，释放资源
            transactionManager.rollBack(transactionInfo);
            throw ex;
        }

        //3.2 提交事务，释放资源
        transactionManager.commit(transactionInfo);
        return res;
    }
}
